/*
 * Copyright 2012 Marsrutai.lt
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package lt.marsrutai.mobile.android.adapter;

import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import lt.marsrutai.mobile.android.AppContext;
import lt.marsrutai.mobile.android.R;
import lt.marsrutai.mobile.android.model.ArrivalTime;
import lt.marsrutai.mobile.android.model.TransportStopBookmark;
import lt.marsrutai.mobile.android.task.GetArrivalTimesTask;
import lt.marsrutai.mobile.android.util.NextDepartures;
import lt.marsrutai.mobile.android.util.StringUtils;
import lt.marsrutai.mobile.android.util.TimeUntilNextDeparture;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class TransportStopBookmarkAdapter extends BookmarkAdapter<TransportStopBookmark> {

    private static Map<TransportStopBookmark, List<ArrivalTime>> arrivalTimeMap = new HashMap<TransportStopBookmark, List<ArrivalTime>>();

    public TransportStopBookmarkAdapter(Context context) {
        super(context, R.layout.bookmark_transport_stop_item);
    }

    @Override
    public View doGetView(final int position, View view, final ViewGroup parent) {
        TransportStopBookmark stopBookmark = getItem(position);

        if (stopBookmark != null) {
            TextView scheduleNumber = (TextView) view.findViewById(R.id.schedule_number);
            scheduleNumber.setText(null);
            scheduleNumber.setBackgroundColor(AppContext.getTransportInfoResolver().resolveTransportColor(stopBookmark.getScopeFolder(),
                    stopBookmark.getTransportId()));

            TextView stopName = (TextView) view.findViewById(R.id.stop_name);
            stopName.setText(stopBookmark.getStopName() + ", " + stopBookmark.getStopDirectionName());

            if (!StringUtils.equalsIgnoreCase(stopBookmark.getScheduleName(), stopBookmark.getScheduleTrackName())) {
                scheduleNumber.setText(stopBookmark.getScheduleName());
            }

            download(view, stopBookmark);
        }

        return super.doGetView(position, view, parent);
    }

    protected static void download(View view, TransportStopBookmark stopBookmark) {
        if (arrivalTimeMap.containsKey(stopBookmark)) {
            List<ArrivalTime> trackStopTimes = arrivalTimeMap.get(stopBookmark);
            
            populateArrivalTimeInfo(view, trackStopTimes);
        }
        else {
            if (cancelPotentialDownload(view, stopBookmark)) {
                GetArrivalTimesTask task = new GetTransportStopArrivalTimesTask(view, stopBookmark);
                view.setTag(task);
                task.execute(new GetArrivalTimesTask.Criteria(stopBookmark.getScopeFolder(), stopBookmark.getStopName(), stopBookmark
                        .getStopId(), 600, 20));
            }
        }
    }

    private static boolean cancelPotentialDownload(View view, TransportStopBookmark stopBookmark) {
        GetTransportStopArrivalTimesTask task = (GetTransportStopArrivalTimesTask) view.getTag();
        
        if (task != null) {
            if (task.stopBookmark != null && task.stopBookmark.equals(stopBookmark)) {
                // same times are already being downloaded
                return false;
            }
            else {
                task.cancel(true);
            }
        }
        return true;
    }
    
    protected static void populateArrivalTimeInfo(View view, List<ArrivalTime> arrivalTimes) {
        TextView nextStopTimes = (TextView) view.findViewById(R.id.next_stop_times);
        nextStopTimes.setText(new NextDepartures(arrivalTimes).toString());

        TextView timeRemaining = (TextView) view.findViewById(R.id.time_remaining);
        timeRemaining.setText(AppContext.getApplicationContext().getString(R.string.after,
                new TimeUntilNextDeparture(arrivalTimes).toString()));
    }

    private static class GetTransportStopArrivalTimesTask extends GetArrivalTimesTask {

        private final WeakReference<View> textViewReference;
        private TransportStopBookmark stopBookmark;

        public GetTransportStopArrivalTimesTask(View view, TransportStopBookmark stopBookmark) {
            this.textViewReference = new WeakReference<View>(view);
            this.stopBookmark = stopBookmark;
        }

        @Override
        protected void onPostExecute(List<ArrivalTime> arrivalTimes) {
            if (isCancelled()) {
                return;
            }

            arrivalTimeMap.put(stopBookmark, arrivalTimes);

            if (textViewReference != null) {
                View view = textViewReference.get();
                if (view != null && view.getTag() == this) {
                    populateArrivalTimeInfo(view, arrivalTimes);
                }
            }
        }
    }

}
